package view;

import interfaces.ViewPanel;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Vector;

import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;

import storage.ManageData;
import utils.CommandGenerator;
import utils.DataFormat;
import utils.KeyboardManager;

import com.toedter.calendar.JDateChooser;

import control.CategoryManager;
import control.ExpenseManager;
import control.LoanManager;
import control.MemberManager;
import control.PaymentMethodManager;
import control.Search;
import control.Shell;
import control.ValidateInput;
import control.ViewPanelManager;
import domain.FamilyMember;
import domain.Loan;
import enums.LoanState;

//@author A0103947A
public class LoanManagerPanel extends BackgroundPanel implements ViewPanel  {
//	public KeyTyped key = new KeyTyped();

	public 	DefaultComboBoxModel<FamilyMember> cbm_expenseMember;	
	public 	DefaultComboBoxModel<FamilyMember> cbm_loanMember;
	
	private JComboBox<FamilyMember> cb_loanByMem;
	private JComboBox <LoanState> cb_loanOrBorrow;	
	private JScrollPane scrollPane_loanList;	
	private JTextField textField_loanIR;
	private JButton btn_addLoan;
	private JButton btn_editLoan;
	private JButton btn_delete;
	
	private JTextField textField_loanName;
	private JDateChooser calendarDate;
	private JDateChooser loanDueDate;	
	private ExpenseManager _xpnManager;
	private Shell _shell;

	private MemberManager _memManager;
	private CategoryManager _catManager;
	private PaymentMethodManager _payManager;
	private LoanManager _loanManager;
	private Search _search;	
	private SidePane _sidePane;
	private ViewPanelManager _tabPanelMgr;
	private Vector<Vector> loanRowData;
	private Loan _loanBeforeEdit;
	
	
	private JTable loanTable;
	
	private JTextField textField_description;
	final JTextField textField_loanAmount;
	private JTextField textField_partyInvolved;

	public LoanManagerPanel(final ExpenseManager xpnManager, final Shell shell, 
			final MemberManager memManager, final CategoryManager catManager, 
			final PaymentMethodManager payManager, final LoanManager loanManager,
			SidePane sidePane, ViewPanelManager tabPanelMgr)
	{		
		
		super();
		
		_xpnManager = xpnManager;
		_shell = shell;
		_memManager = memManager;
		_catManager = catManager;
		_loanManager = loanManager;
		_sidePane = sidePane;
		_tabPanelMgr = tabPanelMgr;
		_loanBeforeEdit = null;
		
		setLayout(null);

		//Textfield associated with "Loan Name" label
		textField_loanName = new JTextField();
		textField_loanName.setColumns(10);
		textField_loanName.setBounds(27, 38, 131, 23);
		this.add(textField_loanName);
		
		JLabel lblAmount = new JLabel("Amount");
		lblAmount.setBounds(27, 65, 122, 17);
		this.add(lblAmount);
		
		textField_loanAmount = new JTextField();
		textField_loanAmount.setColumns(10);
		textField_loanAmount.setBounds(27, 86, 131, 23);
		this.add(textField_loanAmount);
		
		JLabel lblLoanborrow = new JLabel("Loan/Borrow");
		lblLoanborrow.setBounds(27, 185, 80, 16);
		this.add(lblLoanborrow);
		
		cb_loanOrBorrow = new JComboBox<LoanState>();
		cb_loanOrBorrow.setBounds(27, 211, 131, 23);
		cb_loanOrBorrow.addItem(LoanState.BORROWED);
		cb_loanOrBorrow.addItem(LoanState.LENT);
		cb_loanOrBorrow.addItem(LoanState.INVESTMENT);

		this.add(cb_loanOrBorrow);
		
		JLabel lblInterestRate = new JLabel("Interest Rate");
		lblInterestRate.setBounds(27, 247, 80, 16);
		this.add(lblInterestRate);
		
		textField_loanIR = new JTextField();
		textField_loanIR.setColumns(10);
		textField_loanIR.setBounds(27, 269, 131, 23);
		this.add(textField_loanIR);
		
		JLabel lblLoanDue = new JLabel("Loan Due Date");
		lblLoanDue.setBounds(27, 367, 118, 16);
		this.add(lblLoanDue);
		
		// textField associated with "Loan Due(Months)" label
		//final JTextField textField_loanDue = new JTextField();
		//textField_loanDue.setColumns(10);
		//textField_loanDue.setBounds(27, 395, 134, 28);
		//this.add(textField_loanDue);
		loanDueDate = new JDateChooser();
		loanDueDate.setBounds(27, 393, 131, 23);
		loanDueDate.setPreferredSize(new Dimension(90,20));
		loanDueDate.setDateFormatString("dd/MM/yyyy");
		this.add(loanDueDate);
		
		
		scrollPane_loanList = new JScrollPane();
		scrollPane_loanList.setBounds(170, 47, 650, 400);
		this.add(scrollPane_loanList);
		
		
		_search = new Search(_loanManager, _memManager);
		UneditableTable vectorTable = new UneditableTable(null, Search.getToLoanVectorColName());
		loanTable = new JTable(vectorTable);
		loanTable.setFont(new Font("Tahoma", Font.BOLD, 11));
		
		scrollPane_loanList.setViewportView(loanTable);
		
		calendarDate = new JDateChooser();
		calendarDate.setBounds(698, 11, 122, 23);
		calendarDate.setPreferredSize(new Dimension(90,20));
		calendarDate.setDateFormatString("dd/MM/yyyy");
		this.add(calendarDate);
		
		JLabel lblDateDue = new JLabel("Date");
		lblDateDue.setBounds(660, 14, 38, 17);
		this.add(lblDateDue);
		
		btn_addLoan = new JButton("Add Loan");
		btn_addLoan.setBounds(175, 470, 122, 23);
		this.add(btn_addLoan);
		btn_addLoan.addActionListener (new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(!validateInput())
					return;
				String cmd = CommandGenerator.getAddLoanCmd(textField_loanName.getText(), 
						Double.parseDouble(textField_loanAmount.getText()), 
						(LoanState) cb_loanOrBorrow.getSelectedItem(), 
						((FamilyMember) cb_loanByMem.getSelectedItem()).get_id(), 
						((JTextField)calendarDate.getDateEditor().getUiComponent()).getText(), 
						((JTextField)loanDueDate.getDateEditor().getUiComponent()).getText(), 
						Double.parseDouble(textField_loanIR.getText()),
						textField_partyInvolved.getText(),
						textField_description.getText());
				
				shell.readCmd(cmd);
				_tabPanelMgr.updateTable();
				setDefault();
				}

			});
		
		btn_delete = new JButton("Delete Loan");
		btn_delete.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int selectedRow = loanTable.getSelectedRow();
				if(selectedRow>=0)
				{
					int loanId = _search.getLoanIdList().get(selectedRow);
					//System.out.println("delete id: "+ expenseId);
					
					if(_loanManager.get(loanId).get_loanState() == LoanState.BORROWED_CLEARED) {
						int selection = JOptionPane.showConfirmDialog(null, "Are you sure want to delete this loan?\n" +
								"This operation will delete all accompanying \nloan expenses and cannot be undone.",
								"Warning", JOptionPane.YES_NO_OPTION);
						if(selection==JOptionPane.NO_OPTION)
						{
							return;
						}
					}
					else if (_loanManager.get(loanId).get_loanState() == LoanState.LENT_CLEARED || 
							_loanManager.get(loanId).get_loanState() == LoanState.INVESTMENT_CLEARED) {
						int selection = JOptionPane.showConfirmDialog(null, "Are you sure want to delete this loan?\n" +
								"This operation will delete all accompanying \nloan incomes and cannot be undone.",
								"Warning", JOptionPane.YES_NO_OPTION);
						if(selection==JOptionPane.NO_OPTION)
						{
							return;
						}
					}
					
					String cmd = CommandGenerator.getDeleteLoanCmd(loanId);		
					shell.readCmd(cmd);

					_tabPanelMgr.updateTable();
					setDefault();
				}
				else
				{
					print("Please select an existing loan to edit.\n");
				}
			}
		});
		btn_delete.setBounds(687, 470, 122, 23);
		this.add(btn_delete);

		final JButton btn_saveEdit = new JButton();
		btn_saveEdit.setIcon(new ImageIcon(LoanManagerPanel.class.getResource("/images/save.png")));
		btn_saveEdit.setBounds(375, 458, 48, 48);
		btn_saveEdit.setBorderPainted(false);
		btn_saveEdit.setVisible(false);
		btn_saveEdit.setContentAreaFilled(false);
		btn_saveEdit.setFocusable(false);
		add(btn_saveEdit);
		
		final JButton btn_cancelEdit = new JButton();
		btn_cancelEdit.setIcon(new ImageIcon(LoanManagerPanel.class.getResource("/images/cancel.png")));
		btn_cancelEdit.setBounds(553, 458, 48, 48);
		btn_cancelEdit.setBorderPainted(false);
		btn_cancelEdit.setVisible(false);
		btn_cancelEdit.setContentAreaFilled(false);
		btn_cancelEdit.setFocusable(false);
		add(btn_cancelEdit);
		
		JLabel lblMember_1 = new JLabel("By Member");
		lblMember_1.setBounds(27, 121, 118, 16);
		this.add(lblMember_1);
		
		
		cb_loanByMem = new JComboBox<FamilyMember>();
		cb_loanByMem.setBounds(27, 144, 131, 23);
		this.add(cb_loanByMem);
		
		textField_description = new JTextField();
		textField_description.setColumns(10);
		textField_description.setBounds(248, 14, 400, 21);
		this.add(textField_description);
		
		JLabel lblLoanName = new JLabel("Name");
		lblLoanName.setBounds(27, 14, 122, 17);
		add(lblLoanName);
	
		// Code for case where "save" button is pushed
		btn_saveEdit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int selectedRow = loanTable.getSelectedRow();
				if(selectedRow>=0)
				{

					if(!validateInput())
						return;
					// If loan is already in a cleared state, it cannot be edited
					if (_loanBeforeEdit.get_loanState() == LoanState.BORROWED_CLEARED
						|| _loanBeforeEdit.get_loanState() == LoanState.LENT_CLEARED
						|| _loanBeforeEdit.get_loanState() == LoanState.INVESTMENT_CLEARED) {
							JOptionPane.showMessageDialog(null, "This loan has already been cleared. It cannot be edited.");
							setDefault();
							btn_saveEdit.setVisible(false);
							btn_cancelEdit.setVisible(false);
							return;
					}
					int editId = _search.getLoanIdList().get(selectedRow);
					String cmd = CommandGenerator.getEditLoanCmd(
							editId,
							textField_loanName.getText(), 
							Double.parseDouble(textField_loanAmount.getText()), 
							(LoanState) cb_loanOrBorrow.getSelectedItem(), 
							((FamilyMember)cb_loanByMem.getSelectedItem()).get_id(), 
							((JTextField)calendarDate.getDateEditor().getUiComponent()).getText(), 
							((JTextField)loanDueDate.getDateEditor().getUiComponent()).getText(), 
							Double.parseDouble(textField_loanIR.getText()),
							textField_partyInvolved.getText(),
							textField_description.getText());
					
					
					shell.readCmd(cmd);
					_tabPanelMgr.updateTable();
					setDefault();
					
					btn_saveEdit.setVisible(false);
					btn_cancelEdit.setVisible(false);
					setDefault();
				}
			}
		});
		
		// Code for case where "Cancel" button is pushed
		btn_cancelEdit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				setDefault();
				btn_saveEdit.setVisible(false);
				btn_cancelEdit.setVisible(false);
			}
		});
		
		btn_editLoan = new JButton("Edit Loan");
		btn_editLoan.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int selectedRow = loanTable.getSelectedRow();
				if(selectedRow>=0) {
					
					int editId = _search.getLoanIdList().get(selectedRow);
					Loan loan = loanManager.get(editId);
					
					saveLoanBeforeEdit(loan);
			
					textField_loanName.setText(loan.get_name());
					String loanAmount = new String(DataFormat.returnTwoDecimals(loan.get_amount()));
					String loanAmountDisplay = new String(loanAmount.replaceAll(",",""));
					textField_loanAmount.setText(loanAmountDisplay);
					((JTextField)loanDueDate.getDateEditor().getUiComponent()).setText(loan.get_dueDate().toString());
					textField_loanIR.setText(loan.get_interestRate() + "");
					cb_loanByMem.setSelectedItem(_memManager.get(loan.get_byMem().get_id()));
					cb_loanOrBorrow.setSelectedItem(loan.get_loanState());
					((JTextField)calendarDate.getDateEditor().getUiComponent()).setText(loan.get_date().toString());
					textField_description.setText(loan.get_comments());
					textField_partyInvolved.setText(loan.get_partyInvolved());
					
					btn_saveEdit.setVisible(true);
					btn_cancelEdit.setVisible(true);
				}
			}
		});
		btn_editLoan.setBounds(427, 470, 122, 23);
		add(btn_editLoan);
		
		JLabel lblPartyInvolved = new JLabel("Party Involved");
		lblPartyInvolved.setBounds(27, 307, 118, 16);
		add(lblPartyInvolved);
		
		textField_partyInvolved = new JTextField();
		textField_partyInvolved.setBounds(27, 327, 131, 23);
		add(textField_partyInvolved);
		textField_partyInvolved.setColumns(10);
		
		JButton btnAddMem = new JButton("");
		btnAddMem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				KeyboardManager.genKeyEvent(KeyEvent.KEY_PRESSED, KeyEvent.CTRL_DOWN_MASK, KeyEvent.VK_M);
			} 
		});
		btnAddMem.setBorderPainted(false);
		btnAddMem.setContentAreaFilled(false);
		btnAddMem.setFocusable(false);
		btnAddMem.setIcon(new ImageIcon(LoanManagerPanel.class.getResource("/images/user_add.png")));
		btnAddMem.setBounds(3, 144, 24, 24);
		add(btnAddMem);
		
		JLabel lblDescription = new JLabel("Description");
		lblDescription.setBounds(170, 16, 83, 18);
		add(lblDescription);

		
		this.setDefault();
		this.updateAll();
	}
	

	/**
	 * 
	 * @Precondition 
	 * @Postcondition 
	 */
	public void saveLoanBeforeEdit(Loan loan) {
		_loanBeforeEdit = loan;
	}

	/**
	 * 
	 * @Precondition 
	 * @Postcondition 
	 */
	public void setDefault() {
		textField_loanName.setText("");
		textField_loanAmount.setText("");
		((JTextField)loanDueDate.getDateEditor().getUiComponent()).setText("");
		((JTextField)calendarDate.getDateEditor().getUiComponent()).setText("");
		textField_loanIR.setText(Loan.DEFAULT_INTERESTRATE+"");
		cb_loanByMem.setSelectedItem(_memManager.get(0));
		cb_loanOrBorrow.setSelectedItem(Loan.DEFAULT_FREQUENCY);
		textField_partyInvolved.setText("");
		textField_description.setText(Loan.DEFAULT_COMMENTS);
	}
	
	/**
	 * 
	 * @Precondition 
	 * @Postcondition 
	 */
	public void updateTable()
	{
		loanRowData = _search.toLoanVector();
		UneditableTable vectorTable = new UneditableTable(loanRowData, Search.getToLoanVectorColName());
		loanTable = new JTable(vectorTable);
		loanTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		loanTable.addMouseListener(new MouseAdapter() {
			   public void mousePressed(MouseEvent e) {
				      if (e.getClickCount() > 1) {
				         JTable target = (JTable)e.getSource();
				         int row = target.getSelectedRow();
				         int column = target.getSelectedColumn();
				         loanTable.removeEditor();
				         // do some action
				         btn_editLoan.doClick();
				         }
				   }
				});
		
		for (int i = 0; i < 13; i++) {
		loanTable.getColumnModel().getColumn(i).setPreferredWidth(120);
		}
		
		scrollPane_loanList.setViewportView(loanTable);
		loanTable.setRowSelectionAllowed(true);
		_sidePane.update();
		_tabPanelMgr.updateLoan();
	}
	
	/**
	 * 
	 * @Precondition 
	 * @Postcondition 
	 */
	public void updateMember()
	{
		cbm_loanMember = new DefaultComboBoxModel<FamilyMember>();
		for(FamilyMember mem: _memManager.getList())
		{
			cbm_loanMember.addElement(mem);
		}
		cb_loanByMem.setModel(cbm_loanMember);
	}
	
	/**
	 * 
	 * @Precondition 
	 * @Postcondition 
	 */
	public void updateAll()
	{
		updateMember();
		updateTable();
	}
	

	public boolean validateInput()
	{
		if(!ValidateInput.validName(textField_loanName.getText()))
		{
			return false;
		}
		if(!ValidateInput.validAmount(textField_loanAmount.getText()))
		{
			return false;
		}
		if(!ValidateInput.validInterestRate(textField_loanIR.getText(), "Loans")) {
			return false;
		}
		if(!ValidateInput.validPartyInvolved(textField_partyInvolved.getText(),"Party Involved"))
		{
			return false;
		}
		if(!ValidateInput.validDescription(textField_description.getText(),"Description"))
		{
			return false;
		}
		if(!ValidateInput.validMandatoryDate(calendarDate, "Date")) {
			return false;
		}
		if(!ValidateInput.validMandatoryDate(loanDueDate, "Loan Due Date")) {
			return false;
		}
		if(!ValidateInput.validDateOrder(calendarDate, loanDueDate)) {
			return false;
		}
		
		return true;
	}
	
	public void print(String msg)
	{
		_sidePane.appendRecent(msg);
	}

	@Override
	public void updateExpense() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void updateIncome() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void updateLoan() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void updateCategory() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void updatePayMethod() {
		// TODO Auto-generated method stub
		
	}
}
